package com.linh.location;

import java.util.Collections;
import java.util.List;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.DefaultHttpClient;

import android.annotation.TargetApi;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.widget.TableLayout;
import android.widget.TableRow;
import android.widget.TextView;

@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public class BusScheduleActivity extends Activity {

	static final long REFRESH_INTERVAL = 5000;
	public static final String RECOVER_ACTION = "recoverAction";
	static final String REFRESH_ACTION = "refreshAction";
	static final String BUS_SCHEDULE = "busSchedule";
	static final String LAST_BUS_STOP = "lastBusStop";
	private TextView title;
	private TableLayout tableLayout;
	private BusStop busStop;
	private String stopId;

	private HttpUriRequest httpUriRequest;
	private ScheduledThreadPoolExecutor threadPoolExecutor;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_bus_schedule);
		title = (TextView) findViewById(R.id.busStopName);
		tableLayout = (TableLayout) findViewById(R.id.routeLayout);

	}

	@Override
	protected void onStart() {

		super.onStart();
		Intent intent = getIntent();
		// check if it is recover intent
	    stopId = intent.getStringExtra(RECOVER_ACTION);
		busStop = (BusStop) intent
				.getSerializableExtra(BusStop.class.getName());
		updateDisplay(busStop);
		registerReceiver(scheduleReceiver, new IntentFilter(REFRESH_ACTION));
		if (stopId == null) {
			stopId = busStop.getStopId();
		}
		String url = BusUrl.getSingleQuery(
				getResources().getString(R.string.rfl_bus_api_url_prefix),
				stopId);
		httpUriRequest = new HttpGet(url);
		threadPoolExecutor = new ScheduledThreadPoolExecutor(1);
		Runnable task = new BusScheduleUpdate();
		threadPoolExecutor.scheduleAtFixedRate(task, 0, REFRESH_INTERVAL,
				TimeUnit.MILLISECONDS);
	}

	@Override
	protected void onStop() {

		super.onStop();
		// save last bus stop
		if (busStop != null) {
			SharedPreferences preferences = getSharedPreferences(getClass()
					.getSimpleName(), MODE_PRIVATE);
			preferences.edit().putString(LAST_BUS_STOP, busStop.getStopId())
					.commit();
		}
		unregisterReceiver(scheduleReceiver);
		threadPoolExecutor.shutdownNow();
	}

	private void updateDisplay(BusStop busStop) {
		if (busStop != null) {

			tableLayout.removeAllViews();
			title.setText("Stop: " + busStop.getName() + " (auto-update)");
			// add header
			TableRow headerRow = new TableRow(this);
			TextView routeIdHeader = new TextView(this);
			routeIdHeader.setTextAppearance(this, R.style.bus_schedule_style);
			routeIdHeader.setText(getResources().getString(R.string.bus_route));
			headerRow.addView(routeIdHeader);

			

			TextView timeHeader = new TextView(this);
			timeHeader.setText(getResources().getString(R.string.arrival_time));
			timeHeader.setTextAppearance(this, R.style.bus_schedule_style);
			headerRow.addView(timeHeader);
			
			TextView towardHeader = new TextView(this);
			towardHeader.setTextAppearance(this, R.style.bus_schedule_style);
			towardHeader.setText(getResources().getString(
					R.string.bus_destination));
			headerRow.addView(towardHeader);
			tableLayout.addView(headerRow);
			List<BusRoute> routes=busStop.getBusRoutes();
			Collections.sort(routes);
			for (BusRoute busRoute : routes) {
				TableRow tableRow = new TableRow(this);
				String routeId = busRoute.getRouteId();
				String toward = busRoute.getDestinationName() ;
				int waitingTime = busRoute.getWaitingTime();
				int waitingTimeInMin = waitingTime / 60;
				String time = new StringBuilder().append(waitingTimeInMin)
						.append(" min").toString();
				if (waitingTime < 60) {
					time = "due";
				}

				TextView routeIdView = new TextView(this);
				routeIdView.setTextAppearance(this, R.style.bus_schedule_style);
				routeIdView.setText(routeId);
				tableRow.addView(routeIdView);

				

				TextView timeView = new TextView(this);
				timeView.setText(time);
				timeView.setTextAppearance(this, R.style.bus_schedule_style);
				tableRow.addView(timeView);
				
				TextView towardView = new TextView(this);
				towardView.setTextAppearance(this, R.style.bus_schedule_style);
				towardView.setText(toward);
				tableRow.addView(towardView);
				tableLayout.addView(tableRow);

			}

			tableLayout.refreshDrawableState();
		}
	}

	class BusScheduleUpdate implements Runnable {

		private HttpClient httpClient;

		private LocationParser locationParser;

		public BusScheduleUpdate() {
			httpClient = new DefaultHttpClient();
			locationParser = new LocationParser();
		}

		@Override
		public void run() {
			try {
				HttpResponse httpResponse = httpClient.execute(httpUriRequest);
				String result = new BasicResponseHandler()
						.handleResponse(httpResponse);
				Log.i(getClass().getName(), result);
				BusStop update = locationParser.parse(result).get(stopId);
				if (update != null) {

					Intent intent = new Intent(REFRESH_ACTION);
					intent.putExtra(BUS_SCHEDULE, update);
					BusScheduleActivity.this.sendBroadcast(intent);
				}
			} catch (Exception ex) {
				Log.e(getClass().getName(), "Error", ex);
			}

		}
	}

	private BroadcastReceiver scheduleReceiver = new BroadcastReceiver() {

		@Override
		public void onReceive(Context context, Intent intent) {
			BusStop update = (BusStop) intent
					.getSerializableExtra(BUS_SCHEDULE);
			updateDisplay(update);

		}

	};

}
